﻿using System;
using System.Collections.Generic;

namespace FFACETools
{
    public partial class FFACE
    {
        /// <summary>
        /// Class container for position of NPC
        /// </summary>
        public class Position
        {
            #region Members

            /// <summary>
            /// X position of NPC
            /// </summary>
            public float X { get; set; }

            /// <summary>
            /// Y position of NPC
            /// </summary>
            public float Y { get; set; }

            /// <summary>
            /// Z position of NPC
            /// </summary>
            public float Z { get; set; }

            /// <summary>
            /// Heading of NPC
            /// </summary>
            public float H { get; set; }

            #endregion

            #region Methods

            /// <summary>
            /// Determines if the current Position is equal to the passed position
            /// </summary>
            public override bool Equals (object obj)
            {
                bool bResult = false;

                if (obj is Position)
                {
                    if (X.Equals(( (Position)obj ).X)
                        && Y.Equals(( (Position)obj ).Y)
                        && Z.Equals(( (Position)obj ).Z)
                        && H.Equals(( (Position)obj ).H))
                        bResult = true;
                }

                return bResult;

            } // @ public override bool Equals(object obj)

            /// <summary>
            /// Serves as a hash function for a particular type.
            /// </summary>
            public override int GetHashCode ()
            {
                return X.GetHashCode() + Y.GetHashCode() + Z.GetHashCode() + H.GetHashCode();

            } // @ public override int GetHashCode()

            #endregion

        } // @ public class Position

        /// <summary>
        /// Wrapper class for NPC information from FFACE
        /// </summary>
        public class NPCTools
        {
            #region Constructor

            /// <summary>
            /// Constructor
            /// </summary>
            /// <param name="instanceID">Instance ID generated from FFACE</param>
            /// <param name="index">Index of the NPC</param>
            public NPCTools (int instanceID)
            {
                _InstanceID = instanceID;

            } // @ public NPCWrapper(int instanceID)

            #endregion

            #region Members

            /// <summary>
            /// Instance ID generated by FFACE
            /// </summary>
            private int _InstanceID { get; set; }

            #endregion

            #region Methods

            /// <summary>
            /// If the NPC is rendered on the screen
            /// </summary>
            public byte NPCBit (int id)
            {
                return GetNPCBit(_InstanceID, id);

            } // @ public byte NPCBit(int index)

            /// <summary>
            /// Check if NPC is rendered
            /// </summary>
            /// <param name="id">Index of NPC</param>
            /// <returns>True if NPC is rendered</returns>
            public bool IsRendered (int id)
            {
                // Read the Render byte from the NPC array
                byte[] memorybytes = GetRawNPCData(id, 0x104, 1);

                if (memorybytes != null)
                    return ((memorybytes[0] & (1 << 2)) != 0);
                return false;
            }

            /// <summary>
            /// Type of NPC
            /// </summary>
            public NPCType NPCType (int id)
            {
                return GetNPCType(_InstanceID, id);

            } // @ public byte NPCType

            /// <summary>
            /// Whether the NPC is claimed or not
            /// </summary>
            public bool IsClaimed (int id)
            {
                return IsNPCclaimed(_InstanceID, id);

            } // @ public bool IsClaimed

            /// <summary>
            /// Server ID of the person who first claimed the mob
            /// </summary>
            public int ClaimedID (int id)
            {
                return GetNPCclaimID(_InstanceID, id);

            } // @ public bool ClaimedID

            /// <summary>
            /// Whether the NPC is active or not
            /// </summary>
            public bool IsActive (int id)
            {
                return NPCIsActive(_InstanceID, id);

            } // @ public bool IsActive

            /// <summary>
            /// Name of the NPC
            /// </summary>
            public string Name (int id)
            {
                int size = 20;
                byte[] buffer = new byte[size];
                GetNPCName(_InstanceID, id, buffer, ref size);
                if (size <= 0)
                    return String.Empty;
                return System.Text.Encoding.GetEncoding(1252).GetString(buffer, 0, size - 1);

            } // @ public bool Name

            /// <summary>
            /// X position of the NPC
            /// </summary>
            public float PosX (int id)
            {
                return GetNPCPosX(_InstanceID, id);

            } // @ public double PosX

            /// <summary>
            /// Y position of the NPC
            /// </summary>
            public float PosY (int id)
            {
                return GetNPCPosY(_InstanceID, id);

            } // @ public double PosY

            /// <summary>
            /// Z position of the NPC
            /// </summary>
            public float PosZ (int id)
            {
                return GetNPCPosZ(_InstanceID, id);

            } // @ public double PosZ

            /// <summary>
            /// H position of the NPC
            /// </summary>
            public float PosH (int id)
            {
                return GetNPCPosH(_InstanceID, id);

            } // @ public double PosH

            /// <summary>
            /// Gets the position of the NPC
            /// </summary>
            public Position GetPosition (int id)
            {
                return new Position
                {
                    X = GetNPCPosX(_InstanceID, id),
                    Y = GetNPCPosY(_InstanceID, id),
                    Z = GetNPCPosZ(_InstanceID, id),
                    H = GetNPCPosH(_InstanceID, id)
                };

            } // @ public Position GetPosition(short index)

            /// <summary>
            /// NPC's current hit point percent
            /// </summary>
            public short HPPCurrent (int id)
            {
                return GetNPCHPP(_InstanceID, id);

            } // @ public short HPPCurrent

            /// <summary>
            /// NPC's status
            /// </summary>
            public Status Status (int id)
            {
                return GetNPCStatus(_InstanceID, id);

            } // @ public Status Status

            /// <summary>
            /// Uses player index to get PetID
            /// </summary>
            public int PetID (int id)
            {
                return GetNPCPetID(_InstanceID, id);

            } // @ public short PetID

            /// <summary>
            /// NPC's current TP
            /// </summary>
            public short TPCurrent (int id)
            {
                return GetNPCTP(_InstanceID, id);

            } // @ public short TP

            /// <summary>
            /// NPC's distance from player
            /// </summary>
            public double Distance (int id)
            {
                return GetNPCDistance(_InstanceID, id);

            } // @ public double Distance

            /// <summary>
            /// Requires: Index of mob in the NPC Array, Start position and Size of bytes to read
            /// </summary>
            /// <param name="index"></param>
            /// <param name="start"></param>
            /// <param name="size"></param>
            /// <returns></returns>
            public byte[] GetRawNPCData(int mobindex, int start, int size)
            {
                if (size <= 0)
                    return null;
                int _size = size;
                byte[] npcarraybytes = new byte[_size];
                ReadRawNPCData(_InstanceID, mobindex, start, npcarraybytes, ref _size);
                if (_size > 0)
                    return npcarraybytes;
                return null;
            } // @ public byte[] GetRawNPCData

            /// <summary>
            /// Sets the data in the NPC Array for the NPC at the selected mobindex
            /// </summary>
            /// <param name="index"></param>
            /// <param name="start"></param>
            /// <param name="buffer"></param>
            /// <param name="size"></param>
            /// <returns></returns>
            public bool SetRawNPCData (int mobindex, int start, byte[] buffer, int size)
            {
                if (buffer.Length <= 0 || size <= 0)
                    return false;
                return WriteRawNPCData(_InstanceID, mobindex, start, buffer, size);

            } // @ public bool SetRawNPCData

            #endregion

        } // @ public class NPCTools
    } // @ public partial class FFACE
}
